package cate.game.role.bag.fairy;

import cate.common.table.d.GDObj;
import cate.common.table.item.fairy.row.FairyBaseRow;
import cate.common.table.item.fairy.row.FairyPosRow;
import cate.common.util.GameResult;
import cate.game.attr.FairysPowerAttrPart;
import cate.game.attr.PowerAttrPart;
import cate.game.play.support.PlayBuildContext;
import cate.game.role.Role;
import cate.game.role.RoleDependent;
import cate.game.role.bag.IBagContainer;
import cate.game.role.bag.hero.Hero;
import cate.game.role.bag.hero.OnHeroItem;
import com.fasterxml.jackson.annotation.JsonIgnore;
import cp.solution.util.collection.MapKit;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import org.springframework.data.annotation.Transient;

import java.util.*;

@NoteClass(value = "英雄身上的灵器")
public class FairiesOn extends RoleDependent implements OnHeroItem<Fairy>{
    @JsonIgnore
    @Transient
    public transient Hero owner;

    @NoteField(value = "英雄身上的装备们", detail = "Map<部位:Byte, 装备信息>")
    public Map<Byte, Fairy> fairyMap;

    public FairiesOn(){

    }

    public void initialize(Hero owner,Role role){
        super.initialize(role);
        this.owner = owner;
        if(fairyMap == null){
            fairyMap = new HashMap<>();
        }
        fairyMap.values().forEach(a -> a.initialize(role));
    }

    @Override
    @JsonIgnore
    @SuppressWarnings("unchecked")
    public IBagContainer<Fairy> getItemBag() {
        return role.getBag().getBag(GDObj.Type.FAIRY);
    }

    @Override
    public Map<Byte, Fairy> getPosItems() {
        return fairyMap;
    }

    @Override
    public GameResult<Void> preCheckOn(PlayBuildContext ctx, byte pos, Fairy fairy){
        FairyBaseRow row = fairy.getTpl(ctx);
        GameResult<Void> r = new GameResult<>();
        if (row == null) {
            return r.fail("灵器配置有误");
        }
        FairyPosRow posRow = ctx.fairyExcel().pos.getRowByPos(pos);
        if (posRow == null) {
            return r.fail("穿戴栏位有误");
        }
        if (owner.getTpl(ctx).star < posRow.star) {
            return r.fail("英雄星级不够");
        }
        if (owner.getEffectiveLevel() < posRow.level) {
            return r.fail("英雄等级不够");
        }
        if (fairyMap.entrySet().stream()
                .anyMatch(e -> e.getValue().getTpl(ctx).protoId == fairy.getTpl(ctx).protoId && e.getKey() != pos)) {
            return r.fail("无法穿戴相同的灵器");
        }
        return r.success();
    }

    @Override
    public void doRealOn(byte pos, Fairy fairy) {
        // 穿上装备
        fairyMap.put(pos, fairy);
    }

    @Override
    public void doRealOff(byte pos, Fairy fairy) {
        this.fairyMap.remove(pos);
    }

    @Override
    @JsonIgnore
    public PowerAttrPart getPowerAttrPart(PlayBuildContext ctx) {
        return new FairysPowerAttrPart(ctx,this);
    }

    @JsonIgnore
    public List<Integer> getSkills(PlayBuildContext ctx) {
        try {
            Set<Integer> skills = new HashSet<>();
            fairyMap.values().forEach(
                    a -> skills.addAll(a.getSkills(ctx, owner.getTpl(ctx).protoId)));
            return new ArrayList<>(skills);
        }catch (Exception e){
            logger.error("FairysOn getSkills() error", e);
            return new ArrayList<>();
        }
    }

    @Override
    public FairiesOn copy() {
        FairiesOn cp = new FairiesOn();
        cp.fairyMap = MapKit.cloneDeep(this.fairyMap);
        cp.initialize(this.owner, this.role);
        return cp;
    }
}
